package com.shrct.businessprocess.project.impl;

import com.google.common.base.Objects;
import com.shrct.businessprocess.common.Container;
import com.shrct.businessprocess.organization.RCEmployee;
import com.shrct.businessprocess.project.RCCommissionYearConfig;
import com.shrct.businessprocess.project.RCCostShareYearConfigItem;
import com.shrct.businessprocess.project.RCSaleCommissionTotalSettlement;
import com.shrct.businessprocess.project.RCSalesAssignment;
import com.shrct.businessprocess.project.RCSalesCommissionOverflowConfigItem;
import com.shrct.businessprocess.project.RCSalesCommissionYearConfig;
import com.shrct.businessprocess.project.RCSalesCommissionYearSettlement;
import com.shrct.businessprocess.project.RCSalesTeam;
import com.shrct.businessprocess.project.impl.RCSaleCommissionTotalSettlementImpl;
import com.shrct.businessprocess.project.impl.RCSalesCommissionYearConfigImpl;
import com.shrct.businessprocess.project.proxy.RCSalesCommissionYearSettlementProxy;
import edu.fudan.mylang.common.NumberExtensions;
import edu.fudan.mylang.pf.BaseModelObject;
import edu.fudan.mylang.pf.IGenericQuery;
import edu.fudan.mylang.pf.IObjectFactory;
import edu.fudan.mylang.utils.DateUtil;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.DoubleExtensions;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.Functions.Function2;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.hibernate.annotations.DiscriminatorOptions;

@Entity
@DiscriminatorValue("RCSALESCOMMISSIONYEARSETTLEMENT_TYPE")
@DiscriminatorOptions(force = true)
@DiscriminatorColumn(length = 64)
@Table(name = "rcsalescommissionyearsettlement")
public class RCSalesCommissionYearSettlementImpl extends BaseModelObject implements RCSalesCommissionYearSettlement {
  public RCSalesCommissionYearSettlementImpl() {
    super();
  }
  
  public RCSalesCommissionYearSettlementImpl(final RCSaleCommissionTotalSettlement settlement) {
    super();
    this.settlement = settlement;
  }
  
  @JoinColumn(name = "settlement_id")
  @ManyToOne(targetEntity = RCSaleCommissionTotalSettlementImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCSaleCommissionTotalSettlement settlement;
  
  public RCSaleCommissionTotalSettlement getSettlement() {
    return this.settlement;
  }
  
  public RCSalesCommissionYearSettlement setSettlement(final RCSaleCommissionTotalSettlement settlement) {
    this.settlement = settlement;
    return this;			
    
  }
  
  @JoinColumn(name = "yearConfig_id")
  @ManyToOne(targetEntity = RCSalesCommissionYearConfigImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCSalesCommissionYearConfig yearConfig;
  
  public RCSalesCommissionYearConfig getYearConfig() {
    return this.yearConfig;
  }
  
  public RCSalesCommissionYearSettlement setYearConfig(final RCSalesCommissionYearConfig yearConfig) {
    this.yearConfig = yearConfig;
    return this;			
    
  }
  
  public Integer getOnJobMonths() {
    int _xblockexpression = (int) 0;
    {
      Date _xifexpression = null;
      RCSalesAssignment _saler = this.yearConfig.getSaler();
      Date _leaveDate = _saler.getLeaveDate();
      boolean _equals = Objects.equal(_leaveDate, null);
      if (_equals) {
        Date _startDate = this.yearConfig.getStartDate();
        Date _lastDayOfYear = DateUtil.lastDayOfYear(_startDate);
        _xifexpression = _lastDayOfYear;
      } else {
        Date _startDate_1 = this.yearConfig.getStartDate();
        Date _lastDayOfYear_1 = DateUtil.lastDayOfYear(_startDate_1);
        RCSalesAssignment _saler_1 = this.yearConfig.getSaler();
        Date _leaveDate_1 = _saler_1.getLeaveDate();
        Date _min = DateUtil.min(_lastDayOfYear_1, _leaveDate_1);
        _xifexpression = _min;
      }
      final Date lastDay = _xifexpression;
      Date _date = this.settlement.getDate();
      final Date endDay = DateUtil.min(lastDay, _date);
      Date _startDate_2 = this.yearConfig.getStartDate();
      Double _betweenMonth = DateUtil.betweenMonth(_startDate_2, endDay);
      long _round = Math.round((_betweenMonth).doubleValue());
      int _intValue = Long.valueOf(_round).intValue();
      _xblockexpression = (_intValue);
    }
    return Integer.valueOf(_xblockexpression);
  }
  
  public Integer getOnJobMonthsTarget() {
    Integer _onJobMonthsTarget = this.yearConfig.getOnJobMonthsTarget();
    return _onJobMonthsTarget;
  }
  
  public Double getSharedCost() {
    double _xblockexpression = (double) 0;
    {
      RCCommissionYearConfig _overallConfig = this.yearConfig.getOverallConfig();
      Integer _year = _overallConfig.getYear();
      RCSalesAssignment _saler = this.settlement.getSaler();
      RCEmployee _saler_1 = _saler.getSaler();
      IGenericQuery<RCCostShareYearConfigItem> query=getObjectFactory().createGenericQuery(RCCostShareYearConfigItem.class,"select e from com.shrct.businessprocess.project.impl.RCCostShareYearConfigItemImpl as e   where (((e.config.year) = (:_year)) and ((e.shareTarget) = (:_saler_1))) and  e.active = 1      ").setParameter("_year",_year).setParameter("_saler_1",_saler_1);
      final RCCostShareYearConfigItem config = query.uniqueResult();
      double _xifexpression = (double) 0;
      boolean _equals = Objects.equal(config, null);
      if (_equals) {
        _xifexpression = 0d;
      } else {
        Double _totalCost = config.getTotalCost();
        Double _shareRate = config.getShareRate();
        double _multiply = DoubleExtensions.operator_multiply(_totalCost, _shareRate);
        _xifexpression = _multiply;
      }
      _xblockexpression = (_xifexpression);
    }
    return Double.valueOf(_xblockexpression);
  }
  
  private Double contractProfit = Double.valueOf(0d);
  
  public Double getContractProfit() {
    return this.contractProfit;
  }
  
  public RCSalesCommissionYearSettlement setContractProfit(final Double contractProfit) {
    this.contractProfit = contractProfit;
    return this;			
    
  }
  
  private Double totalContractProfit = Double.valueOf(0d);
  
  public Double getTotalContractProfit() {
    return this.totalContractProfit;
  }
  
  public RCSalesCommissionYearSettlement setTotalContractProfit(final Double totalContractProfit) {
    this.totalContractProfit = totalContractProfit;
    return this;			
    
  }
  
  private Double contractProfitAdj4Sale = Double.valueOf(0d);
  
  public Double getContractProfitAdj4Sale() {
    return this.contractProfitAdj4Sale;
  }
  
  public RCSalesCommissionYearSettlement setContractProfitAdj4Sale(final Double contractProfitAdj4Sale) {
    this.contractProfitAdj4Sale = contractProfitAdj4Sale;
    return this;			
    
  }
  
  public Double getCommisstionTarget() {
    Double _totalCost = this.getTotalCost();
    double _minus = DoubleExtensions.operator_minus(this.contractProfitAdj4Sale, _totalCost);
    return Double.valueOf(_minus);
  }
  
  public Double getCommissionAmountTarget() {
    double _xifexpression = (double) 0;
    Double _commisstionTarget = this.getCommisstionTarget();
    Double _baseGrossProfitGoal = this.getBaseGrossProfitGoal();
    boolean _greaterEqualsThan = (_commisstionTarget.compareTo(_baseGrossProfitGoal) >= 0);
    if (_greaterEqualsThan) {
      Double _commisstionTarget_1 = this.getCommisstionTarget();
      Double _rate = this.yearConfig.getRate();
      double _multiply = DoubleExtensions.operator_multiply(_commisstionTarget_1, _rate);
      _xifexpression = _multiply;
    } else {
      _xifexpression = 0d;
    }
    return Double.valueOf(_xifexpression);
  }
  
  private Double cggp = Double.valueOf(0d);
  
  public Double getCggp() {
    return this.cggp;
  }
  
  public RCSalesCommissionYearSettlement setCggp(final Double cggp) {
    this.cggp = cggp;
    return this;			
    
  }
  
  public Double getCGGP4Commisstion() {
    Double _totalCost = this.getTotalCost();
    double _minus = DoubleExtensions.operator_minus(this.cggp, _totalCost);
    return Double.valueOf(_minus);
  }
  
  public Double getCGGP4CommissionAmount() {
    Double _cGGP4Commisstion = this.getCGGP4Commisstion();
    Double _rate = this.yearConfig.getRate();
    double _multiply = DoubleExtensions.operator_multiply(_cGGP4Commisstion, _rate);
    return Double.valueOf(_multiply);
  }
  
  public Double getCommissionAmount() {
    Double _xifexpression = null;
    boolean _and = false;
    Double _baseGrossProfitGoal = this.getBaseGrossProfitGoal();
    boolean _greaterThan = (this.cggp.compareTo(_baseGrossProfitGoal) > 0);
    if (!_greaterThan) {
      _and = false;
    } else {
      Double _commissionAmountTarget = this.getCommissionAmountTarget();
      boolean _greaterThan_1 = ((_commissionAmountTarget).doubleValue() > 0);
      _and = (_greaterThan && _greaterThan_1);
    }
    if (_and) {
      Double _cGGP4CommissionAmount = this.getCGGP4CommissionAmount();
      _xifexpression = _cGGP4CommissionAmount;
    } else {
      _xifexpression = 0d;
    }
    return _xifexpression;
  }
  
  public Double getTotalCost() {
    Double _additionalSharedCost = this.yearConfig.getAdditionalSharedCost();
    Double _totalPaidSalary = this.getTotalPaidSalary();
    double _plus = DoubleExtensions.operator_plus(_additionalSharedCost, _totalPaidSalary);
    Double _sharedCost = this.getSharedCost();
    double _plus_1 = (_plus + (_sharedCost).doubleValue());
    return Double.valueOf(_plus_1);
  }
  
  public Double getTotalPaidSalary() {
    Integer _onJobMonths = this.getOnJobMonths();
    Double _monthlySalary = this.yearConfig.getMonthlySalary();
    double _multiply = ((_onJobMonths).intValue() * (_monthlySalary).doubleValue());
    return Double.valueOf(_multiply);
  }
  
  public Double getBaseGrossProfitGoal() {
    double _xblockexpression = (double) 0;
    {
      Double _additionalSharedCost = this.yearConfig.getAdditionalSharedCost();
      Integer _onJobMonths = this.getOnJobMonths();
      double _divide = DoubleExtensions.operator_divide(_additionalSharedCost, _onJobMonths);
      Integer _onJobMonthsTarget = this.getOnJobMonthsTarget();
      double _multiply = (_divide * (_onJobMonthsTarget).intValue());
      Double _totalSalaryTarget = this.getTotalSalaryTarget();
      double _plus = (_multiply + (_totalSalaryTarget).doubleValue());
      Double _baseGrossProfitGoalFactor = this.yearConfig.getBaseGrossProfitGoalFactor();
      double _multiply_1 = (_plus * (_baseGrossProfitGoalFactor).doubleValue());
      Double _sharedCost = this.getSharedCost();
      final double actialBaseGrossProfitGoal = (_multiply_1 + (_sharedCost).doubleValue());
      Double _baseGrossProfitGoal = this.yearConfig.getBaseGrossProfitGoal();
      double _max = Math.max((_baseGrossProfitGoal).doubleValue(), actialBaseGrossProfitGoal);
      _xblockexpression = (_max);
    }
    return Double.valueOf(_xblockexpression);
  }
  
  public Double getTotalSalaryTarget() {
    Integer _onJobMonthsTarget = this.getOnJobMonthsTarget();
    Double _monthlySalary = this.yearConfig.getMonthlySalary();
    double _multiply = ((_onJobMonthsTarget).intValue() * (_monthlySalary).doubleValue());
    return Double.valueOf(_multiply);
  }
  
  /**
   * K81 本年度预计超额倍数
   */
  public Double getOverflowTimesTarget() {
    Double _totalCost = this.getTotalCost();
    Integer _onJobMonths = this.getOnJobMonths();
    double _divide = DoubleExtensions.operator_divide(_totalCost, _onJobMonths);
    Integer _onJobMonthsTarget = this.getOnJobMonthsTarget();
    double _multiply = (_divide * (_onJobMonthsTarget).intValue());
    double _minus = ((this.contractProfitAdj4Sale).doubleValue() - _multiply);
    Double _baseGrossProfitGoal = this.getBaseGrossProfitGoal();
    double _divide_1 = (_minus / (_baseGrossProfitGoal).doubleValue());
    return Double.valueOf(_divide_1);
  }
  
  public Double getOverflowTimes() {
    double _xblockexpression = (double) 0;
    {
      Double _cGGP4Commisstion = this.getCGGP4Commisstion();
      Double _baseGrossProfitGoal = this.getBaseGrossProfitGoal();
      final double result = DoubleExtensions.operator_divide(_cGGP4Commisstion, _baseGrossProfitGoal);
      double _xifexpression = (double) 0;
      boolean _lessThan = (result < 0);
      if (_lessThan) {
        _xifexpression = 0d;
      } else {
        _xifexpression = result;
      }
      _xblockexpression = (_xifexpression);
    }
    return Double.valueOf(_xblockexpression);
  }
  
  /**
   * 计算超额奖，采用层级算法
   * 
   * total : 总金额
   * unit :  保底毛利
   */
  public Double calcOverflowCommissionAmount(final Double total, final Double unit) {
    Double _xblockexpression = null;
    {
      Collection<RCSalesCommissionOverflowConfigItem> _overflowConfigItems = this.yearConfig.getOverflowConfigItems();
      int _size = _overflowConfigItems.size();
      boolean _equals = (_size == 0);
      if (_equals) {
        return Double.valueOf(0d);
      }
      final Container con = Container.put(total);
      Collection<RCSalesCommissionOverflowConfigItem> _overflowConfigItems_1 = this.yearConfig.getOverflowConfigItems();
      final Function1<RCSalesCommissionOverflowConfigItem,Double> _function = new Function1<RCSalesCommissionOverflowConfigItem,Double>() {
          public Double apply(final RCSalesCommissionOverflowConfigItem it) {
            Double _multiple = it.getMultiple();
            return _multiple;
          }
        };
      final List<RCSalesCommissionOverflowConfigItem> configItems = IterableExtensions.<RCSalesCommissionOverflowConfigItem, Double>sortBy(_overflowConfigItems_1, _function);
      final ArrayList<Double> segments = CollectionLiterals.<Double>newArrayList();
      final Function1<RCSalesCommissionOverflowConfigItem,Double> _function_1 = new Function1<RCSalesCommissionOverflowConfigItem,Double>() {
          public Double apply(final RCSalesCommissionOverflowConfigItem item) {
            Double _multiple = item.getMultiple();
            double _multiply = DoubleExtensions.operator_multiply(unit, _multiple);
            Double _takeIncremental = con.takeIncremental(Double.valueOf(_multiply));
            return _takeIncremental;
          }
        };
      List<Double> _map = ListExtensions.<RCSalesCommissionOverflowConfigItem, Double>map(configItems, _function_1);
      final Procedure1<Double> _function_2 = new Procedure1<Double>() {
          public void apply(final Double it) {
            segments.add(it);
          }
        };
      IterableExtensions.<Double>forEach(_map, _function_2);
      Double _remain = con.getRemain();
      segments.add(_remain);
      List<Double> _reverse = ListExtensions.<Double>reverse(segments);
      final Iterator<Double> reversedSegments = _reverse.iterator();
      List<RCSalesCommissionOverflowConfigItem> _reverse_1 = ListExtensions.<RCSalesCommissionOverflowConfigItem>reverse(configItems);
      final Function1<RCSalesCommissionOverflowConfigItem,Double> _function_3 = new Function1<RCSalesCommissionOverflowConfigItem,Double>() {
          public Double apply(final RCSalesCommissionOverflowConfigItem it) {
            double _xblockexpression = (double) 0;
            {
              final Double nextReversedSegment = reversedSegments.next();
              Double _rate = it.getRate();
              double _multiply = DoubleExtensions.operator_multiply(_rate, nextReversedSegment);
              _xblockexpression = (_multiply);
            }
            return Double.valueOf(_xblockexpression);
          }
        };
      List<Double> _map_1 = ListExtensions.<RCSalesCommissionOverflowConfigItem, Double>map(_reverse_1, _function_3);
      final Function2<Double,Double,Double> _function_4 = new Function2<Double,Double,Double>() {
          public Double apply(final Double d1, final Double d2) {
            double _plus = DoubleExtensions.operator_plus(d1, d2);
            return Double.valueOf(_plus);
          }
        };
      Double _reduce = IterableExtensions.<Double>reduce(_map_1, _function_4);
      Double _nullsafe = NumberExtensions.nullsafe(_reduce);
      _xblockexpression = (_nullsafe);
    }
    return _xblockexpression;
  }
  
  public Double getOverflowCommissionAmountTarget() {
    Double _commisstionTarget = this.getCommisstionTarget();
    Double _baseGrossProfitGoal = this.getBaseGrossProfitGoal();
    Double _calcOverflowCommissionAmount = this.calcOverflowCommissionAmount(_commisstionTarget, _baseGrossProfitGoal);
    return _calcOverflowCommissionAmount;
  }
  
  public Double getOverflowCommissionAmount() {
    Double _cGGP4Commisstion = this.getCGGP4Commisstion();
    Double _baseGrossProfitGoal = this.getBaseGrossProfitGoal();
    Double _calcOverflowCommissionAmount = this.calcOverflowCommissionAmount(_cGGP4Commisstion, _baseGrossProfitGoal);
    return _calcOverflowCommissionAmount;
  }
  
  /**
   * 团队管理奖
   */
  public Double getTeamPrizeAmount() {
    Collection<RCSalesTeam> _teams = this.yearConfig.getTeams();
    final Function1<RCSalesTeam,Double> _function = new Function1<RCSalesTeam,Double>() {
        public Double apply(final RCSalesTeam it) {
          Double _prizeAmount = it.getPrizeAmount();
          return _prizeAmount;
        }
      };
    Iterable<Double> _map = IterableExtensions.<RCSalesTeam, Double>map(_teams, _function);
    final Function2<Double,Double,Double> _function_1 = new Function2<Double,Double,Double>() {
        public Double apply(final Double d1, final Double d2) {
          double _plus = DoubleExtensions.operator_plus(d1, d2);
          return Double.valueOf(_plus);
        }
      };
    Double _reduce = IterableExtensions.<Double>reduce(_map, _function_1);
    Double _nullsafe = NumberExtensions.nullsafe(_reduce);
    return _nullsafe;
  }
  
  public Double getTeamPrizeAmountTarget() {
    Collection<RCSalesTeam> _teams = this.yearConfig.getTeams();
    final Function1<RCSalesTeam,Double> _function = new Function1<RCSalesTeam,Double>() {
        public Double apply(final RCSalesTeam it) {
          Double _prizeAmountTarget = it.getPrizeAmountTarget();
          return _prizeAmountTarget;
        }
      };
    Iterable<Double> _map = IterableExtensions.<RCSalesTeam, Double>map(_teams, _function);
    final Function2<Double,Double,Double> _function_1 = new Function2<Double,Double,Double>() {
        public Double apply(final Double d1, final Double d2) {
          double _plus = DoubleExtensions.operator_plus(d1, d2);
          return Double.valueOf(_plus);
        }
      };
    Double _reduce = IterableExtensions.<Double>reduce(_map, _function_1);
    Double _nullsafe = NumberExtensions.nullsafe(_reduce);
    return _nullsafe;
  }
  
  public Double getTotalAmountToPay() {
    Double _commissionAmount = this.getCommissionAmount();
    Double _nullsafe = NumberExtensions.nullsafe(_commissionAmount);
    Double _overflowCommissionAmount = this.getOverflowCommissionAmount();
    Double _nullsafe_1 = NumberExtensions.nullsafe(_overflowCommissionAmount);
    double _plus = DoubleExtensions.operator_plus(_nullsafe, _nullsafe_1);
    Double _teamPrizeAmount = this.getTeamPrizeAmount();
    Double _nullsafe_2 = NumberExtensions.nullsafe(_teamPrizeAmount);
    double _plus_1 = (_plus + (_nullsafe_2).doubleValue());
    return Double.valueOf(_plus_1);
  }
  
  /**
   * 预计佣金合计
   */
  public Double getTotalAmountTarget() {
    Double _commissionAmountTarget = this.getCommissionAmountTarget();
    Double _overflowCommissionAmountTarget = this.getOverflowCommissionAmountTarget();
    double _plus = DoubleExtensions.operator_plus(_commissionAmountTarget, _overflowCommissionAmountTarget);
    Double _teamPrizeAmountTarget = this.getTeamPrizeAmountTarget();
    double _plus_1 = (_plus + (_teamPrizeAmountTarget).doubleValue());
    return Double.valueOf(_plus_1);
  }
  
  public static RCSalesCommissionYearSettlement create(final RCSaleCommissionTotalSettlement settlement, final IObjectFactory objectFactory) {
    com.shrct.businessprocess.project.RCSalesCommissionYearSettlement rCSalesCommissionYearSettlement = new com.shrct.businessprocess.project.impl.RCSalesCommissionYearSettlementImpl(
    	settlement
    );
    objectFactory.create(rCSalesCommissionYearSettlement);
    return rCSalesCommissionYearSettlement;			
    
  }
  
  public static RCSalesCommissionYearSettlement createRCSalesCommissionYearSettlementImpl(final RCSaleCommissionTotalSettlement settlement, final IObjectFactory objectFactory, final Procedure1<RCSalesCommissionYearSettlement> init) {
    com.shrct.businessprocess.project.RCSalesCommissionYearSettlement rCSalesCommissionYearSettlement = new com.shrct.businessprocess.project.impl.RCSalesCommissionYearSettlementImpl(
    	settlement
    );
    objectFactory.create(rCSalesCommissionYearSettlement);
    init.apply(rCSalesCommissionYearSettlement);
    
    return rCSalesCommissionYearSettlement;			
    
  }
  
  public RCSalesCommissionYearSettlementProxy toProxy() {
    com.shrct.businessprocess.project.proxy.RCSalesCommissionYearSettlementProxy proxy = new com.shrct.businessprocess.project.proxy.RCSalesCommissionYearSettlementProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    return proxy;
    
  }
}
